#ifndef PBVP_MULTI_CONTREE_H
#define PBVP_MULTI_CONTREE_H

#include <QString>

#include "dualgraph.h"

namespace PBVP {
	///	Multi-resolution dual contour tree (MACT)
	/**
	* 
	*/
	class MultiConTree
	{
	public:
		/// Constructor
		MultiConTree(DualGraph *pDCTree);

		/// Destructor
		virtual ~MultiConTree();

		/// Compute the SimScore between two MACTs with individual set of attributes
		SimScore match(MultiConTree &mact2);

		///	Maximum level of the MACT
		int maxLevel() const {
			return m_MaxLevel;
		}

		/// get the total normalized volume of the dual tree
		float totalVolume() const {
			float vol = 0;
			for (int i = 0; i < m_DualTrees[0]->numOfNodes(0); i++)
			{
				vol += m_DualTrees[0]->getNode(0, i)->normVolume;
			}
			return vol;
		}

		/// Prune small nodes of volume < threshold
		void prune(float threshold); 

		/// Get the center of mass and principal axes of nodes at level l and range k
		// void getPCS(int l, int k, float *ctr, float **axes);

		/// Get the pointer to one DualNode in the MACT
		/**
		* 
		* @param level
		* @param range
		* @param id
		* 
		* @return DualNode*
		*/
		DualNode* getNodePtr(int level, int range, int id) {
			return m_DualTrees[level]->node(range, id);
		}

		///
		float getPruneThreshold() const {
			return m_PruneThreshold;
		}

		/// 
		void setPruneThresholde(float threshold) {
			m_PruneThreshold = threshold;
		}

		/// Convert info about this MACT to a QString
		QString toQString() const;

	protected:
		///
		int m_MaxLevel;
		///
		DualGraph** m_DualTrees;
		///
		float m_PruneThreshold; 

	private:
		///	Search for the best match for a dual node
		DualNode* matchSearch(DualNode* dualnode, DualGraph* graph);

		///	The matching score between two nodes
		float matchScore(DualNode *node1, DualNode *node2);

		/// Clear the all matching bits
		void clearMatchs()
		{
			for (int i = 0; i <= m_MaxLevel; i++)
			{
				for (int j = 0; j < m_DualTrees[i]->numOfRanges(); j++)
				{
					for (int k = 0; k < m_DualTrees[i]->numOfNodes(j); k++)
					{
						m_DualTrees[i]->node(j, k)->clearMatch(); //match = NULL;
					}
				}
			}
		}
	};
}
#endif
